/*********************************************************
          File Name:hash.h
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Sat 01 Aug 2015 09:10:07 PM CST
**********************************************************/

#ifndef HASH_H_
#define HASH_H_

#define DEFAULT_NUM     309
#define DEFAULT_RATIO   3

#ifdef __x86_64
typedef unsigned long size_t;
#else
typedef unsigned int size_t;
#endif


static inline unsigned long do_hash(char *s)
{
        unsigned int hash = 5381;
        int c;

        while((c = *s++))
                hash = ((hash << 5) + hash) + c;
        return hash;
}

typedef struct node {
        char *key;
        char *val;              // handle one key, char **val for keys
        struct node *next;
} hash_node_t;

typedef struct hashtable {
        unsigned int elements;        // how many key-pair in table
        unsigned int in_use;           // used hash table array size
        unsigned int key_ratio;
        hash_node_t **node;
} hash_table_t;

typedef enum {
        LINE_BAD,       /* allocate memory failed */
        LINE_CMT,       /* start with '#' or '\n' */
        LINE_EOL,       /* '\0' */
        LINE_OK,        /* key-value pair */
} line_t;

hash_node_t *hash_node_new(void);

void hash_node_delete(hash_node_t *node);

hash_table_t *hash_table_new(void);

void hash_table_delete(hash_table_t *table);

// reutrn value: 0 OK, -1 key too long, -2 can't allocate space
int hash_add(hash_table_t *table, char *key, char *value);

// remove node by giving key and key_len
int hash_remove(hash_table_t *table, char *key);

// return value or NULL(key not found) by giving key and key_len
char *hash_getval(hash_table_t *table, char *key);

// get key-value pairs; store them in an array
int hash_getpairs(hash_table_t *table, hash_node_t ***node);

int hash_resize(hash_table_t *table, unsigned int len);

//---------------------------------------------------
// read all key-value pairs into a initailized hash table
int file2hash(const char *path, hash_table_t *ht, size_t *offset);

#endif
